/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  							 script_army_boolean_expression.cpp

	$Header: /heroes4/script_army_boolean_expression.cpp $

	$NoKeywords: $

 ************************************************************************/

// kill the 255+ character identifier warning.  Templates tend to exceed that easily.
#include "precompiled.h"
#pragma warning( disable: 4786 )

#include "script_army_boolean_expression.h"

#include "creature_array.h"
#include "hero.h"
#include "script_targeting.h"
#include "sized_int_types.h"
#include "streambuf_operators.h"
#include "string_insensitive_compare.h"
#include "town_type.h"

// --------------------------------------------------------------------------
// t_script_army_has_alignment members
// --------------------------------------------------------------------------

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
bool t_script_army_has_alignment::read_from_map(
	std::streambuf &	stream,
	int					format_version )
{
	if ( !t_script_army_boolean_expression::read_from_map( stream, format_version ) )
		return false;

	m_alignment = t_alignment( get< t_uint8 >( stream ) );
	return m_alignment >= 0 && m_alignment < k_town_type_count;
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
bool t_script_army_has_alignment::read( std::streambuf& stream, int	version )
{
	if ( !t_script_army_boolean_expression::read( stream, version ) )
		return false;

	m_alignment = get< t_alignment >( stream );
	
	return true;
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
bool t_script_army_has_alignment::write( std::streambuf& stream ) const
{
	if ( !t_script_army_boolean_expression::write( stream ) )
		return false;

	put< t_alignment >( stream, m_alignment );
	
	return true;
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
t_script_army_has_alignment::t_result 
t_script_army_has_alignment::evaluate(t_expression_context_hero const& context) const
{
	t_creature_array const* array = select_army_by_target(get_target(), NULL, context.army, context.opposing_army);
	return do_evaluate(array);
}

t_script_army_has_alignment::t_result 
t_script_army_has_alignment::evaluate(t_expression_context_town const& context) const
{
	t_creature_array const* array = select_army_by_target(get_target(), context.garrison, NULL, context.opposing_army);
	return do_evaluate(array);

}

t_script_army_has_alignment::t_result 
t_script_army_has_alignment::evaluate(t_expression_context_object const& context) const
{
	assert(false);
	return false;
}

t_script_army_has_alignment::t_result 
t_script_army_has_alignment::evaluate(t_expression_context_army const& context) const
{
	t_creature_array const* array = select_army_by_target(get_target(), NULL, context.army, context.opposing_army);
	return do_evaluate(array);
}

t_script_army_has_alignment::t_result 
t_script_army_has_alignment::evaluate(t_expression_context_global const& context) const
{
	assert(false);
	return false;
}

t_script_army_has_hero::t_result 
t_script_army_has_alignment::do_evaluate(t_creature_array const* array) const
{
	if (array == NULL) return false;
	for (int i = 0; i < t_creature_array::k_size; i++) 
	{
		if ((*array)[i].get_alignment() == get_alignment())
			return true;
	}
	return false;
}

// --------------------------------------------------------------------------
// t_script_army_has_hero members
// --------------------------------------------------------------------------

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
bool t_script_army_has_hero::read_from_map(
	std::streambuf &	stream,
	int					format_version )
{
	return		t_script_army_boolean_expression::read_from_map( stream, format_version )
			&&	read_string16( stream, m_hero_name );
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
bool t_script_army_has_hero::read( std::streambuf& stream, int version )
{
	if (!t_script_army_boolean_expression::read( stream, version ))
		return false;
	
	return read_string16( stream, m_hero_name );
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
bool t_script_army_has_hero::write( std::streambuf& stream ) const
{
	if (!t_script_army_boolean_expression::write( stream ))
		return false;
	
	return write_string16( stream, m_hero_name );
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
t_script_army_has_hero::t_result 
t_script_army_has_hero::evaluate(t_expression_context_hero const& context) const
{
	t_creature_array const* array = select_army_by_target(get_target(), NULL, context.army, context.opposing_army);
	return do_evaluate(array);
}

t_script_army_has_hero::t_result 
t_script_army_has_hero::evaluate(t_expression_context_town const& context) const
{
	t_creature_array const* array = select_army_by_target(get_target(), context.garrison, NULL, context.opposing_army);
	return do_evaluate(array);

}

t_script_army_has_hero::t_result 
t_script_army_has_hero::evaluate(t_expression_context_object const& context) const
{
	assert(false);
	return false;
}

t_script_army_has_hero::t_result 
t_script_army_has_hero::evaluate(t_expression_context_army const& context) const
{
	t_creature_array const* array = select_army_by_target(get_target(), NULL, context.army, context.opposing_army);
	return do_evaluate(array);
}

t_script_army_has_hero::t_result 
t_script_army_has_hero::evaluate(t_expression_context_global const& context) const
{
	assert(false);
	return false;
}

t_script_army_has_hero::t_result 
t_script_army_has_hero::do_evaluate(t_creature_array const* array) const
{
	if (array == NULL) return false;
	for (int i = 0; i < t_creature_array::k_size; i++) 
	{
		const t_hero* hero = (*array)[i].get_hero();
		if (hero && (string_insensitive_compare(hero->get_name(), get_hero_name()) == 0))
			return true;
	}
	return false;
}

